<template>
  <el-table
    v-bind="$attrs"
    :data="tableData"
    v-loading="isLoading"
    :element-loading-text="elementLoadingText"
    :element-loading-spinner="elementLoadingSpinner"
    :element-loading-background="elementLoadingBackground"
    :element-loading-svg="elementLoadingSvg"
    :element-loading-svg-view-box="elementLoadingSvgViewBox"
    @row-click="rowClick"
  >
    <!-- 每行 -->
    <template v-for="(item, index) in tableOptions" :key="index">
      <el-table-column
        :label="item.label"
        :prop="item.prop"
        :width="item.width"
        :align="item.align"
      >
        <!-- 存在特殊列样式时 -->
        <template #default="scope">
          <!-- 可编辑单元行 -->
          <template v-if="scope.row.rowEdit">
            <el-input size="small" v-model="scope.row[item.prop]"></el-input>
          </template>
          <!-- 插槽单元格 可编辑单元格/特殊样式单元格 -->
          <template v-else>
            <!-- 单元格编辑框 -->
            <template v-if="scope.$index + scope.column.id === currentEdit">
              <div style="display: flex">
                <el-input
                  v-model="scope.row[item.prop]"
                  size="small"
                  placeholder="请输入"
                />
                <!-- 阻止事件冒泡 -->
                <div @click.stop="clickEditCell(scope)">
                  <!-- 用户可替换的 编辑和关闭 -->
                  <slot
                    name="editCell"
                    :scope="scope"
                    v-if="$slots.editCell"
                  ></slot>
                  <div class="icons" v-else>
                    <el-icon-check
                      class="check"
                      @click="check(scope)"
                    ></el-icon-check>
                    <el-icon-close
                      class="close"
                      @click="close(scope)"
                    ></el-icon-close>
                  </div>
                </div>
              </div>
            </template>
            <!-- 单元内容 -->
            <template v-else>
              <!-- 自定义展示单元内容 -->
              <slot v-if="item.slot" :name="item.slot" :scope="scope"></slot>
              <!-- 默认只展示数据 -->
              <span v-else>{{ scope.row[item.prop] }}</span>
              <component
                class="edit"
                v-if="item.editable"
                :is="`el-icon-${toLine(props.editIcon)}`"
                @click.stop="edit(scope)"
              >
                <!-- 阻止事件冒泡 -->
              </component>
            </template>
          </template>
        </template>
      </el-table-column>
    </template>
    <!-- 最后一列 操作列 -->
    <el-table-column
      v-if="actionOptions"
      :label="actionOptions.label"
      :align="actionOptions.align"
      :width="actionOptions.width"
    >
      <!-- 编辑,删除 操作列 -->
      <template #default="scope">
        <slot name="editRow" :scope="scope" v-if="scope.row.rowEdit"></slot>
        <!-- 把element的表格当前数据分发出去-->
        <slot name="action" :scope="scope" v-else></slot>
      </template>
    </el-table-column>
  </el-table>

  <div
    v-if="pagination && !isLoading"
    class="pagination"
    :style="{ justifyContent }"
  >
  <!-- 官网和视频里面都是v-model的curretn-page,但是会报错, 改成bind先 -->
    <el-pagination
      :current-page="currentPage"
      :page-sizes="pageSizes"
      :page-size="pageSize"
      layout="total, sizes, prev, pager, next, jumper"
      :total="total"
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
    ></el-pagination>
  </div>
</template>

<script setup lang="ts">
import { PropType, computed, onMounted, ref, watch } from "vue";
import { TableOptions } from "components/table/src/types.ts";
import { cloneDeep } from "lodash";
import { toLine } from "@/utils/index.ts";

let props = defineProps({
  options: {
    type: Array as PropType<TableOptions[]>,
    required: true,
  },
  data: {
    type: Array as PropType<any[]>,
    required: true,
  },
  //加载文案
  elementLoadingText: {
    type: String,
  },
  elementLoadingSpinner: {
    type: String,
  },
  elementLoadingBackground: {
    type: String,
  },
  elementLoadingSvg: {
    type: String,
  },
  elementLoadingSvgViewBox: {
    type: String,
  },
  //可编辑单元格的图标
  editIcon: {
    type: String,
    default: "edit",
  },
  //是否可以编辑行
  isEditRow: {
    type: Boolean,
    default: false,
  },
  //编辑行按钮的标识
  editRowIndex: {
    type: String,
    default: "",
  },
  // 是否显示分页
  pagination: {
    type: Boolean,
    default: false,
  },
  // 显示分页的对齐方式
  paginationAlign: {
    type: String as PropType<"left" | "center" | "right">,
    default: "left",
  },
  // 当前是第几页
  currentPage: {
    type: Number,
    default: 1,
  },
  // 当前一页多少条数据
  pageSize: {
    type: Number,
    default: 10,
  },
  // 显示分页数据多少条的选项
  pageSizes: {
    type: Array,
    default: () => [10, 20, 30, 40],
  },
  // 数据总条数
  total: {
    type: Number,
    default: 0,
  },
});

let emits = defineEmits([
  "check",
  "close",
  "update:editRowIndex",
  "size-change",
  "current-change",
]);

//表格数据
let tableData = ref<any[]>(cloneDeep(props.data));
// 编辑行按钮的标识
let cloneEditRowIndex = ref<string>(props.editRowIndex);

// 表格分页的排列方式
let justifyContent = computed(() => {
  if (props.paginationAlign === "left") return "flex-start";
  else if (props.paginationAlign === "right") return "flex-end";
  else return "center";
});

// 分页的每一页数据变化
let handleSizeChange = (val: number) => {
  emits("size-change", val);
  // console.log(val)
};
// 分页页数改变
let handleCurrentChange = (val: number) => {
  emits("current-change", val);
  // console.log(val)
};

//数据初始化
onMounted(() => {
  tableData.value.map((item, index) => {
    item.rowEdit = false;
  });
});
// 编辑行标识的变化
watch(
  () => props.editRowIndex,
  (newVal) => {
    if (newVal) cloneEditRowIndex.value = newVal;
  }
);
// 数据的变化监听
watch(
  () => props.data,
  (newVal) => {
    tableData.value = cloneDeep(newVal);
    console.log("table watch ", newVal);
    tableData.value.map((item, index) => {
      item.rowEdit = false;
    });
  },
  { deep: true }
);

let currentEdit = ref<string>();

let isLoading = computed(() => {
  return !props.data || props.data.length === 0;
});

//过滤出非操作选项
let tableOptions = computed(() => {
  return props.options.filter((item) => !item.action);
});

//过滤器出操作项
let actionOptions = computed(() => {
  return props.options.find((item) => item.action);
});

// 点击单元格的编辑图标, 出现下面两个按钮
let edit = (scope: any) => {
  console.log("子组件单元格编辑", scope);
  currentEdit.value = scope.$index + scope.column.id;
};

let check = (scope: any) => {
  emits("check", scope);
  console.log("子组件确认", scope);
};

let close = (scope: any) => {
  emits("close", scope);
  console.log("子组件取消", scope);
};

let clickEditCell = (scope: any) => {
  currentEdit.value = "";
  console.log("子组件统一关闭", scope);
};

// 点击行的事件
let rowClick = (row: any, column: any) => {
  // 判断是否是点击的操作项
  console.log("rowClick", column);
  if (column.label === actionOptions.value!.label) {
    if (props.isEditRow && cloneEditRowIndex.value === props.editRowIndex) {
      // 编辑行的操作
      row.rowEdit = !row.rowEdit;
      // 重置其他数据的rowEdit
      tableData.value.map((item) => {
        if (item !== row) item.rowEdit = false;
      });
      if (!row.rowEdit) emits("update:editRowIndex", "");
    }
  }
};
</script>

<style scoped lang="scss">
.edit {
  width: 1em;
  height: 1em;
  position: relative;
  top: 2px;
  margin-left: 4px;
  transition: all 0.25s linear;
  cursor: pointer;
}

.icons {
  display: flex;
  svg {
    width: 1em;
    height: 1em;
    margin-left: 8px;
    position: relative;
    top: 6px;
    cursor: pointer;
  }
  .check {
    color: red;
  }
  .close {
    color: green;
  }
}
.pagination {
  margin-top: 16px;
  display: flex;
}
</style>
